#!/bin/bash

# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

# 打印带颜色的消息
print_info() {
    echo -e "${BLUE}[INFO]${NC} $1"
}

print_success() {
    echo -e "${GREEN}[SUCCESS]${NC} $1"
}

print_warning() {
    echo -e "${YELLOW}[WARNING]${NC} $1"
}

print_error() {
    echo -e "${RED}[ERROR]${NC} $1"
}

# 检查必要工具
check_prerequisites() {
    print_info "检查必要工具..."
    
    if ! command -v kubectl &> /dev/null; then
        print_error "kubectl 未安装或未在 PATH 中"
        exit 1
    fi
    
    if ! command -v helm &> /dev/null; then
        print_error "helm 未安装或未在 PATH 中"
        exit 1
    fi
    
    # 检查 kubectl 是否能连接到集群
    if ! kubectl cluster-info &> /dev/null; then
        print_error "无法连接到 Kubernetes 集群"
        exit 1
    fi
    
    print_success "所有必要工具检查通过"
}

# 获取用户输入
get_user_input() {
    print_info "开始交互式配置..."
    
    # 获取计算节点主机名
    echo
    print_info "请输入计算节点主机名："
    kubectl get nodes --no-headers | grep -v -E "master|control-plane" | awk '{print "  - " $1}'
    echo
    read -p "请输入第一个节点名称（用于部署 Dify 组件）: " COMPUTE_NODE1
    read -p "请输入第二个节点名称（用于部署 openGauss）: " COMPUTE_NODE2
    
    # 验证节点是否存在
    if ! kubectl get node "$COMPUTE_NODE1" &> /dev/null; then
        print_error "节点 $COMPUTE_NODE1 不存在"
        exit 1
    fi
    
    if ! kubectl get node "$COMPUTE_NODE2" &> /dev/null; then
        print_error "节点 $COMPUTE_NODE2 不存在"
        exit 1
    fi
    
    # 获取 Helm 发布名称
    echo
    read -p "请输入 Helm 发布名称 [默认: myrelease]: " RELEASE_NAME
    RELEASE_NAME=${RELEASE_NAME:-myrelease}
    
    # 获取服务访问端口
    echo
    read -p "请输入服务访问端口 [默认: 8100]: " SERVICE_PORT
    SERVICE_PORT=${SERVICE_PORT:-8100}
    
    # 获取服务器IP
    echo
    print_info "请输入服务器IP地址（用于外部访问）:"
    print_warning "提示: 这应该是您的 Kubernetes 集群可访问的外部IP地址"
    read -p "服务器IP: " SERVER_IP
    
    # 验证IP格式
    if [[ ! $SERVER_IP =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
        print_error "IP地址格式不正确"
        exit 1
    fi
    
    # 确认配置
    echo
    print_info "配置确认:"
    echo "  Dify 节点: $COMPUTE_NODE1"
    echo "  openGauss 节点: $COMPUTE_NODE2"
    echo "  发布名称: $RELEASE_NAME"
    echo "  服务端口: $SERVICE_PORT"
    echo "  服务器IP: $SERVER_IP"
    echo
    read -p "确认以上配置? (y/N): " CONFIRM
    
    if [[ ! $CONFIRM =~ ^[Yy]$ ]]; then
        print_info "部署已取消"
        exit 0
    fi
}

label_nodes() {
    print_info "正在标记节点..."
    
    # 标记 Dify 节点
    if kubectl label nodes $COMPUTE_NODE1 kubernetes.io/node=difyNode --overwrite; then
        print_success "节点 $COMPUTE_NODE1 已标记为 difyNode"
    else
        print_error "标记节点 $COMPUTE_NODE1 失败"
        exit 1
    fi
    
    # 标记 openGauss 节点
    if kubectl label nodes $COMPUTE_NODE2 kubernetes.io/node=dbNode --overwrite; then
        print_success "节点 $COMPUTE_NODE2 已标记为 dbNode"
    else
        print_error "标记节点 $COMPUTE_NODE2 失败"
        exit 1
    fi
    
    print_success "节点标记完成"
}

# 检查端口是否被占用
check_port() {
    local port=$1
    if ss -tuln | grep ":$port " > /dev/null; then
        print_warning "端口 $port 可能已被占用，请检查是否会产生冲突"
        read -p "是否继续? (y/N): " CONTINUE
        if [[ ! $CONTINUE =~ ^[Yy]$ ]]; then
            print_info "部署已取消"
            exit 0
        fi
    fi
}

# 部署 Dify
deploy_dify() {
    print_info "开始部署 Dify..."
    
    # 检查端口
    check_port $SERVICE_PORT
    
    # 执行 Helm 部署 - 使用默认配置
    if helm install $RELEASE_NAME ./dify; then
        print_success "Dify 部署命令执行成功"
    else
        print_error "Dify 部署失败"
        exit 1
    fi
}

# 等待 Pod 就绪
wait_for_pods() {
    print_info "等待 Pod 就绪..."
    
    local max_wait=600  # 最大等待时间（秒）
    local wait_time=0
    local check_interval=10
    
    while [ $wait_time -lt $max_wait ]; do
        # 获取所有相关 Pod 的状态
        local pods_status=$(kubectl get pods -l app.kubernetes.io/instance=$RELEASE_NAME --no-headers 2>/dev/null)
        
        if [ -z "$pods_status" ]; then
            print_warning "未找到相关 Pod，继续等待..."
        else
            echo "$pods_status"
            
            # 检查是否所有 Pod 都处于 Running 状态
            local not_ready=$(echo "$pods_status" | grep -v "Running\|Completed" | wc -l)
            
            if [ $not_ready -eq 0 ]; then
                print_success "所有 Pod 已就绪"
                return 0
            fi
        fi
        
        print_info "等待中... ($wait_time/$max_wait 秒)"
        sleep $check_interval
        wait_time=$((wait_time + check_interval))
    done
    
    print_warning "等待超时，但部署可能仍在进行中"
    print_info "您可以使用以下命令检查状态："
    echo "  kubectl get pods -l app.kubernetes.io/instance=$RELEASE_NAME"
    echo "  kubectl logs -l app.kubernetes.io/instance=$RELEASE_NAME"
}

# 设置端口转发
setup_port_forward() {
    print_info "设置端口转发..."

    # 获取 NodePort
    local node_port=$(kubectl get service myrelease-dify -o jsonpath='{.spec.ports[0].nodePort}' 2>/dev/null)

    if [ -n "$node_port" ]; then
        local access_url="http://$SERVER_IP:$node_port"
        print_success "服务已通过 NodePort 暴露"
        print_success "访问地址: $access_url"
        print_info "请手动在浏览器中访问: $access_url"
    else
        local access_url="http://$SERVER_IP:$SERVICE_PORT"
        print_info "启动端口转发: $SERVICE_PORT -> 服务"
        print_success "访问地址: $access_url"
        print_info "请手动在浏览器中访问: $access_url"
        print_warning "端口转发将在前台运行，按 Ctrl+C 停止"
        echo

        # 启动端口转发到服务
        kubectl port-forward --address 0.0.0.0 service/myrelease-dify $SERVICE_PORT:80
    fi
}

# 显示部署信息
show_deployment_info() {
    echo
    print_success "=== 部署完成 ==="
    echo
    print_info "部署信息:"
    echo "  发布名称: $RELEASE_NAME"
    echo "  服务端口: $SERVICE_PORT"
    echo "  服务器IP: $SERVER_IP"
    echo
    print_info "有用的命令:"
    echo "  查看 Pod 状态: kubectl get pods -l app.kubernetes.io/instance=$RELEASE_NAME"
    echo "  查看服务状态: kubectl get services -l app.kubernetes.io/instance=$RELEASE_NAME"
    echo "  查看 Pod 日志: kubectl logs -l app.kubernetes.io/instance=$RELEASE_NAME"
    echo "  删除部署: helm uninstall $RELEASE_NAME"
    echo
}

# 主函数
main() {
    print_info "开始 Dify Kubernetes 部署"
    echo
    
    # 检查前置条件
    check_prerequisites
    
    # 获取用户输入
    get_user_input

    # 标记节点
    label_nodes    

    # 部署 Dify
    deploy_dify
    
    # 等待 Pod 就绪
    wait_for_pods
    
    # 显示部署信息
    show_deployment_info
    
    # 设置端口转发
    setup_port_forward
}

# 错误处理
set -e
trap 'print_error "脚本执行过程中发生错误，部署可能未完成"' ERR

# 执行主函数
main "$@"

